﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OracleCompare.Core;

namespace OracleCompare
{
    public class CompareUtiity
    {
        private OracleHelper oh1;
        private OracleHelper oh2;
        bool _isTable = false;
        bool _isView = false;
        bool _isProc = false;
        private FrmMain _app;
        private bool _isCompareContent = false;
        private string _tableCondition;
        private string _viewCondition;
        private string _procCondition;
        private string _tableUnCondition;
        private string _viewUnCondition;
        private string _procUnCondition;


        public CompareUtiity(string ser1, string user1, string pwd1,
            string ser2, string user2, string pwd2,
            bool IsTable, bool IsView, bool IsProc,
            string TableCondition, string ViewCondition, string ProcCondition,
            string TableUnCondition, string ViewUnCondition, string ProcUnCondition,
            FrmMain app, bool IsCompareContent)
        {
            _app = app;
            oh1 = new OracleHelper(ser1, user1, pwd1);
            oh2 = new OracleHelper(ser2, user2, pwd2);
            _isTable = IsTable;
            _isView = IsView;
            _isProc = IsProc;
            _isCompareContent = IsCompareContent;
            _tableCondition = TableCondition;
            _viewCondition = ViewCondition;
            _procCondition = ProcCondition;
            _tableUnCondition = TableUnCondition;
            _viewUnCondition = ViewUnCondition;
            _procUnCondition = ProcUnCondition;
        }

        public CompareUtiity(string ser1, string user1, string pwd1,
            string ser2, string user2, string pwd2,
            bool IsTable, bool IsView, bool IsProc,
            FrmMain app, bool IsCompareContent)
            : this(ser1, user1, pwd1, ser2, user2, pwd2, IsTable, IsView, IsProc,
            null, null, null, null, null, null, app, false)
        { }

        public CompareUtiity(string ser1, string user1, string pwd1,
            string ser2, string user2, string pwd2,
            bool IsTable, bool IsView, bool IsProc,
            FrmMain app)
            : this(ser1, user1, pwd1, ser2, user2, pwd2,
            IsTable, IsView, IsProc, app, false)
        { }

        public List<CompareEntity> Compare()
        {
            List<CompareEntity> result = new List<CompareEntity>();

            if (_isTable)
            {
                DateTime dts = DateTime.Now;
                _app.LogMsg("开始比较表...");
                List<TableEntity> tables = ConpareTable();
                foreach (TableEntity temp in tables)
                {
                    CompareEntity ce = new CompareEntity();
                    ce.Name = temp.TableName;
                    ce.Type = "Table";
                    result.Add(ce);
                }
                DateTime dte = DateTime.Now;
                TimeSpan ts = dte - dts;
                _app.LogMsg("表比较已完成，差异表个数:" + tables.Count + "个，耗时:" + ts.TotalSeconds + "秒;");
            }

            if (_isView)
            {
                DateTime dts = DateTime.Now;
                _app.LogMsg("开始比较视图...");
                List<ViewEntity> views = ConpareView();
                foreach (ViewEntity temp in views)
                {
                    CompareEntity ce = new CompareEntity();
                    ce.Name = temp.ViewName;
                    ce.Type = "View";
                    result.Add(ce);
                }
                DateTime dte = DateTime.Now;
                TimeSpan ts = dte - dts;
                _app.LogMsg("视图比较已完成，差异视图个数:" + views.Count + "个，耗时:" + ts.TotalSeconds + "秒;");
            }

            if (_isProc)
            {
                DateTime dts = DateTime.Now;
                _app.LogMsg("开始比较过程...");
                List<ProcedureEntity> procedures = ConpareProcdure();
                foreach (ProcedureEntity temp in procedures)
                {
                    CompareEntity ce = new CompareEntity();
                    ce.Name = temp.Name;
                    ce.Type = "Procedure" + ":" + temp.Type;
                    result.Add(ce);
                }
                DateTime dte = DateTime.Now;
                TimeSpan ts = dte - dts;
                _app.LogMsg("过程比较已完成，差异过程个数:" + procedures.Count + "个，耗时:" + ts.TotalSeconds + "秒;");
            }

            return result;
        }

        private List<TableEntity> ConpareTable()
        {
            List<TableEntity> results = new List<TableEntity>();
            List<TableEntity> tables1 = oh1.GetOracleTables(_tableCondition, _tableUnCondition);
            List<TableEntity> tables2 = oh2.GetOracleTables(_tableCondition, _tableUnCondition);
            foreach (TableEntity table in tables1)
            {
                bool IsExist = tables2.Exists(r => r.TableName == table.TableName);

                if (!IsExist)
                {
                    results.Add(table);
                }
            }

            return results;
        }

        private List<ColumnEntity> ConpareColumn()
        {
            List<ColumnEntity> results = new List<ColumnEntity>();
            List<ColumnEntity> columns1 = oh1.GetOracleColumns();
            List<ColumnEntity> columns2 = oh2.GetOracleColumns();
            foreach (ColumnEntity column in columns1)
            {
                bool IsExist = columns2.Exists(r => r.ColumnName == column.ColumnName &&
                        r.TableName == column.TableName);

                if (!IsExist)
                {
                    results.Add(column);
                }
            }

            return results;
        }

        private List<ViewEntity> ConpareView()
        {
            List<ViewEntity> results = new List<ViewEntity>();
            List<ViewEntity> views1 = oh1.GetOracleViews(_viewCondition, _viewUnCondition);
            List<ViewEntity> views2 = oh2.GetOracleViews(_viewCondition, _viewUnCondition);
            foreach (ViewEntity ve in views1)
            {
                bool IsExist = false;
                if (_isCompareContent)
                {
                    IsExist = views2.Exists(r => r.ViewName == ve.ViewName && r.Text == ve.Text);
                }
                else
                {
                    IsExist = views2.Exists(r => r.ViewName == ve.ViewName);
                }

                if (!IsExist)
                {
                    results.Add(ve);
                }
            }

            return results;
        }

        private List<ProcedureEntity> ConpareProcdure()
        {
            List<ProcedureEntity> results = new List<ProcedureEntity>();
            List<ProcedureEntity> procedure1 = oh1.GetOracleProcedures(_procCondition, _procUnCondition, _isCompareContent);
            List<ProcedureEntity> procedure2 = oh2.GetOracleProcedures(_procCondition, _procUnCondition, _isCompareContent);
            foreach (ProcedureEntity procedure in procedure1)
            {
                bool IsExist = false;
                if (_isCompareContent)
                {
                    IsExist = procedure2.Exists(r => r.Name == procedure.Name &&
                        r.Type == procedure.Type && r.Text == procedure.Text);
                }
                else
                {
                    IsExist = procedure2.Exists(r => r.Name == procedure.Name &&
                        r.Type == procedure.Type);
                }

                if (!IsExist)
                {
                    results.Add(procedure);
                }
            }

            return results;
        }



    }
}
